
package net.swa.dewei.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import net.swa.dewei.beans.entity.ChongdianZhan;
import net.swa.dewei.service.ChongdianZhanService;
import net.swa.system.dao.HibernateDaoSupport;
import net.swa.util.BuzConst;
import net.swa.util.DateUtils;
import net.swa.util.JsonResult;
import net.swa.util.geography.GqueryUtil;
import net.swa.util.geography.VoSquare;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.transform.Transformers;
import org.hibernate.type.StandardBasicTypes;
import org.springframework.stereotype.Service;

@Service("chongdianZhanService")
public class ChongdianZhanServiceImpl extends HibernateDaoSupport implements ChongdianZhanService
{
    private final Logger log = Logger.getLogger(ChongdianZhanServiceImpl.class);

    // 求两点相聚距离
    private double calcfunction(double lat , double lng , ChongdianZhan menDian)
    {
        double EARTH_RADIUS = 6378.137;// 地球半径
        double radLat1 = rad(lat);
        double radLat2 = rad(menDian.getLatitude());
        double a = radLat1 - radLat2;
        double b = rad(lng) - rad(menDian.getLongitude());
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2) + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000) / 10;

        log.debug("两点间距离：" + s);
        return s;// Math.pow((menDian.getLatitude() - lat), 2) +
        // Math.pow(menDian.getLongitude() - lng, 2);
    }

    private double rad(double d)
    {
        return d * Math.PI / 180.0;
    }

    @Override
    public JsonResult<String> add(ChongdianZhan model , boolean isadmin)
    {
        JsonResult<String> json = new JsonResult<String>();
        try
        {
            Session session = getCurrentSession();
            Query q = null;
            if (null != model.getFuwuzhanId() && (!isadmin))
            {
                if ((!StringUtils.isBlank(model.getProvince())) && (!StringUtils.isBlank(model.getCity())))
                {
                    String sql = "select count(*) as countNum  from t_FuwuZhan f join t_FuwuZhanArea a on f.id=a.fuwuzhanId where f.id=:id and ( (f.province like :province1 and f.city like :city1 ) or (a.province like :province1 and a.city like :city1 ))";

                    if (!StringUtils.isBlank(model.getTown()))
                    {
                        sql = "select count(*) as countNum  from t_FuwuZhan f join t_FuwuZhanArea a on f.id=a.fuwuzhanId where f.id=:id and ( (f.province like :province1 and f.city like :city1 and f.town like :town1 ) or (a.province like :province1 and a.city like :city1 and a.town like :town1))";
                    }

                    q = session.createSQLQuery(sql).addScalar("countNum", StandardBasicTypes.INTEGER);
                    q.setLong("id", model.getFuwuzhanId());
                    String province = model.getProvince();
                    q.setString("province1", province.substring(0, (province.length() - 1)) + "%");
                    q.setString("city1", model.getCity().substring(0, (model.getCity().length() - 1)) + "%");
                    if (!StringUtils.isBlank(model.getTown()))
                    {
                        q.setString("town1", model.getTown().substring(0, (model.getTown().length() - 1)) + "%");
                    }

                    int totalCount = (Integer) q.uniqueResult();
                    if (totalCount < 1)
                    {
                        json.setSuccess(false);
                        json.setMessage("该区域不允许您设置充电站！");
                        return json;
                    }
                }
                else
                {
                    json.setSuccess(false);
                    json.setMessage("请标注您充电站的位置，确保包含省市信息");
                    return json;
                }
            }
            model.setCrateDate(DateUtils.getCurrDate(null));
            model.setStatus(BuzConst.STATUS_YES);
            session.save(model);
            json.setSuccess(true);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            json.setSuccess(false);
            json.setMessage(e.toString());
        }
        return json;
    }

    @Override
    public JsonResult<String> update(ChongdianZhan model , boolean isadmin)
    {
        JsonResult<String> json = new JsonResult<String>();
        try
        {
            Session session = getCurrentSession();
            Query q = null;
            if (null != model.getFuwuzhanId() && (!isadmin))
            {
                if ((!StringUtils.isBlank(model.getProvince())) && (!StringUtils.isBlank(model.getCity())))
                {
                    String sql = "select count(*) as countNum  from t_FuwuZhan f join t_FuwuZhanArea a on f.id=a.fuwuzhanId where f.id=:id and ( (f.province like :province1 and f.city like :city1 ) or (a.province like :province1 and a.city like :city1 ))";

                    if (!StringUtils.isBlank(model.getTown()))
                    {
                        sql = "select count(*) as countNum  from t_FuwuZhan f join t_FuwuZhanArea a on f.id=a.fuwuzhanId where f.id=:id and ( (f.province like :province1 and f.city like :city1 and f.town like :town1 ) or (a.province like :province1 and a.city like :city1 and a.town like :town1))";
                    }

                    q = session.createSQLQuery(sql).addScalar("countNum", StandardBasicTypes.INTEGER);
                    q.setLong("id", model.getFuwuzhanId());
                    String province = model.getProvince();
                    q.setString("province1", province.substring(0, (province.length() - 1)) + "%");
                    q.setString("city1", model.getCity().substring(0, (model.getCity().length() - 1)) + "%");
                    if (!StringUtils.isBlank(model.getTown()))
                    {
                        q.setString("town1", model.getTown().substring(0, (model.getTown().length() - 1)) + "%");
                    }

                    int totalCount = (Integer) q.uniqueResult();
                    if (totalCount < 1)
                    {
                        json.setSuccess(false);
                        json.setMessage("该区域不允许您开店！");
                        return json;
                    }
                }
                else
                {
                    json.setSuccess(false);
                    json.setMessage("请标注您开店的位置，确保包含省市信息");
                    return json;
                }
            }
            model.setStatus(BuzConst.STATUS_YES);
            model.setUpdateDate(DateUtils.getCurrDate(null));
            session.update(model);
            //修改位置后不主动同步
            //            if (null != model.getMendianId())
            //            {
            //                q = session .createQuery("update t_MenDian set address=:address,province=:province,city=:city,town=:town,latitude=:lat,longitude=:lng  where id=:id ");
            //                q.setString("address", model.getAddress());
            //                q.setString("province", model.getProvince());
            //                q.setString("city", model.getCity());
            //                q.setString("town", model.getTown());
            //                q.setDouble("lat", model.getLatitude());
            //                q.setDouble("lng", model.getLongitude());
            //                q.setLong("id", model.getMendianId());
            //                q.executeUpdate();
            //            }
            json.setSuccess(true);
        }
        catch (Exception e)
        {
            e.printStackTrace();
            json.setSuccess(false);
            json.setMessage(e.toString());
        }
        return json;
    }

    @Override
    public boolean delete(final Long[] ids)
    {
        for (int i = 0; i < ids.length; i++)
        {
            Query query = null;
            query = getCurrentSession().createQuery(
                    "update ChongdianZhan set status=" + BuzConst.STATUS_NO + " where id=:id");
            query.setLong("id", ids[i]);
            query.executeUpdate();
        }
        return true;
    }

    @Override
    public JsonResult<ChongdianZhan> queryChongdianZhanPage(final String name , final String addr , final String lxr ,
            final int currentPage , final int pageSize , final String orderBy , final String orderType)
    {
        JsonResult<ChongdianZhan> json = new JsonResult<ChongdianZhan>();
        StringBuilder sql = new StringBuilder();
        StringBuilder countsql = new StringBuilder();
        Query query = null;
        countsql.append("select count(1) as counNum  from  t_ChongdianZhan m where 1=1 ");
        sql
                .append("select m.address, m.city, m.crateDate, m.detailInfo, m.fuwuzhanId, m.id, m.imageUrl, m.latitude, m.longitude, m.lxr, m.lxrTel, m.name, m.province, m.town, m.updateDate, m.wxid from  t_ChongdianZhan m   where 1=1 ");

        sql.append(" and m.status=" + BuzConst.STATUS_YES + " ");
        countsql.append(" and m.status=" + BuzConst.STATUS_YES + " ");

        if (!StringUtils.isBlank(name))
        {
            sql.append("  and m.name  like :name");
            countsql.append(" and m.name  like :name");
        }
        if (!StringUtils.isBlank(lxr))
        {
            sql.append(" and m.lxr  like :lxr");
            countsql.append(" and m.lxr  like :lxr");
        }

        if (!StringUtils.isBlank(addr))
        {
            sql.append(" and m.address  like :addr");
            countsql.append(" and m.address  like :addr");
        }

        if (!StringUtils.isBlank(orderBy))
        {
            sql.append("order by " + orderBy);
            if (!StringUtils.isBlank(orderType))
            {
                sql.append("  " + orderType);
            }
        }
        query = getCurrentSession().createSQLQuery(sql.toString()).addScalar("id", StandardBasicTypes.LONG).addScalar(
                "address", StandardBasicTypes.STRING).addScalar("city", StandardBasicTypes.STRING).addScalar(
                "crateDate", StandardBasicTypes.STRING).addScalar("detailInfo", StandardBasicTypes.STRING).addScalar(
                "fuwuzhanId", StandardBasicTypes.LONG).addScalar("imageUrl", StandardBasicTypes.STRING).addScalar(
                "latitude", StandardBasicTypes.DOUBLE).addScalar("longitude", StandardBasicTypes.DOUBLE).addScalar(
                "lxr", StandardBasicTypes.STRING).addScalar("lxrTel", StandardBasicTypes.STRING).addScalar("name",
                StandardBasicTypes.STRING).addScalar("province", StandardBasicTypes.STRING).addScalar("town",
                StandardBasicTypes.STRING).addScalar("updateDate", StandardBasicTypes.STRING).addScalar("wxid",
                StandardBasicTypes.STRING).setResultTransformer(Transformers.aliasToBean(ChongdianZhan.class));

        if (!StringUtils.isBlank(addr))
        {
            query.setString("addr", "%" + addr + "%");
        }
        if (!StringUtils.isBlank(name))
        {
            query.setString("name", "%" + name + "%");
        }
        if (!StringUtils.isBlank(lxr))
        {
            query.setString("lxr", "%" + lxr + "%");
        }

        if (pageSize > 0)
        {
            int from = (currentPage - 1) * pageSize;
            query.setFirstResult(from);
            query.setMaxResults(pageSize);
        }
        List<ChongdianZhan> list = query.list();
        query = getCurrentSession().createSQLQuery(countsql.toString())
                .addScalar("counNum", StandardBasicTypes.INTEGER);
        if (!StringUtils.isBlank(addr))
        {
            query.setString("addr", "%" + addr + "%");
        }
        if (!StringUtils.isBlank(name))
        {
            query.setString("name", "%" + name + "%");
        }
        if (!StringUtils.isBlank(lxr))
        {
            query.setString("lxr", "%" + lxr + "%");
        }
        if (pageSize > 0)
        {
            int totalCount = (Integer) query.uniqueResult();
            int totalPage = totalCount % pageSize == 0 ? totalCount / pageSize : totalCount / pageSize + 1;
            json.setTotalSize(totalCount);
            json.setTotalPage(totalPage);
            json.setPageSize(pageSize);
            json.setCurrentPage(currentPage);
        }
        json.setResult(list);
        return json;
    }

    @Override
    public List<ChongdianZhan> queryMendianByLatLng(Double lat , Double lng , Integer d)
    {
        if (null == d)
        {
            d = 20;
        }
        final VoSquare v = GqueryUtil.querySquarePoint(lng, lat, 20);
        //查询有效的门店
        String hql = "from ChongdianZhan where  status=" + BuzConst.STATUS_YES
                + " and longitude>=:minLng and longitude<=:maxLng and  latitude>=:minLat AND latitude<=:maxLat";
        Query query = getCurrentSession().createQuery(hql);
        query.setDouble("minLng", v.getMinLng());
        query.setDouble("maxLng", v.getMaxLng());
        query.setDouble("minLat", v.getMinLat());
        query.setDouble("maxLat", v.getMaxLat());
        List<ChongdianZhan> list = query.list();
        List<ChongdianZhan> list2 = null;
        if (null != list && list.size() > 0)
        {
            for (int i = 0; i < list.size(); i++)
            {
                double dis = calcfunction(lat, lng, list.get(i));

                ChongdianZhan o = list.get(i);
                log.debug("门店：" + o.getName() + ",距离您" + dis + ",您的经纬度：" + lat + "," + lng + ";门店的经纬度："
                        + o.getLatitude() + "," + o.getLongitude());
                o.setDoubleDistance(dis);
                if (dis >= 1000)
                {
                    java.text.DecimalFormat df = new java.text.DecimalFormat("0.0");
                    o.setDistance(df.format(dis / 1000) + "公里");
                }
                else if (dis > 100)
                {
                    java.text.DecimalFormat df = new java.text.DecimalFormat("0");
                    o.setDistance(df.format(dis / 100) + "00米");
                }
                else
                {
                    o.setDistance("100米");
                }
            }

            Collections.sort(list);
            log.debug("查询结果如下：");
            list2 = new ArrayList<ChongdianZhan>();
            for (int i = 0; i < 5 && i < list.size(); i++)
            {
                if (i == 0)
                {
                    list.get(i).setTuijian(true);
                }
                else
                {
                    list.get(i).setTuijian(false);
                }
                log.debug("门店：" + list.get(i).getName() + ",\n距离您" + list.get(i).getDistance() + ",\n门店经纬度："
                        + list.get(i).getLatitude() + "," + list.get(i).getLongitude());
                list2.add(list.get(i));
            }
        }
        return list2;
    }
}